package ss.pku.jsa.type.test;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.Path;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import ss.pku.jsa.type.inference.Analysis;
import ss.pku.jsa.type.inference.JqualPlugin;
import ss.pku.jsa.type.inference.MethodQType;
import ss.pku.jsa.type.io.AnnotationStore;
import ss.pku.jsa.type.io.AnnotationWriter;
import ss.pku.jsa.type.io.FieldQSig;

@SuppressWarnings({"rawtypes","unchecked"})
public class CommandLine implements IApplication {
	IWorkspaceRoot root = JqualPlugin.getWorkspace().getRoot();
	String rootPath = this.root.getLocation().toString() + "/";

	public Object run(Object argsObj) {
		JqualPlugin.runFromCommandLine = true;

		String dir = System.getProperty("dir");
		if (dir != null) {
			System.out.println("Experiment: " + dir);
		}

		try {
			IFile f = this.root.getFileForLocation(new Path(
					"/home/dgreenfi/eclipse32/cl_test/Test.java"));
			System.out.println(f);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

		return null;
	}

	List<IPackageFragment> getPackages(IProject p) {
		IJavaProject jp = JavaCore.create(p);
		List ret = new Vector();
		try {
			IPackageFragmentRoot r = jp.findPackageFragmentRoot(jp.getPath());
			if (r.getElementName().contains(".jar"))
				JqualPlugin.out.println("Ignoring jar file: "
						+ r.getElementName());
			else {
				for (IJavaElement c : r.getChildren())
					ret.add((IPackageFragment) c);
			}
		} catch (JavaModelException e) {
			throw new RuntimeException(e.toString());
		}
		return ret;
	}

	Analysis analyzeProj(String name) {
		IProject proj = this.root.getProject("/" + name);
		List folders = new LinkedList();
		for (IOpenable element : getPackages(proj)) {
			folders.add(element);
		}
		IOpenable[] inputs = (IOpenable[]) folders.toArray(new IOpenable[1]);
		return JqualPlugin.analyze(inputs, false);
	}

	Analysis jtds() {
		return analyzeProj("jtds-1.2");
	}

	AnnotationStore getAnnotationStore(Analysis a) {
		AnnotationStore store = new AnnotationStore();
		storeAnnotations(store, a);
		return store;
	}

	public void storeAnnotations(AnnotationStore store, Analysis a) {
		for (MethodQType m : a.getOriginalMethodQTypes())
			store.put(m.methodQSig());
	}

	static void outputQualifierResults(String name, Analysis a) {
		JqualPlugin.out.println("Writing results to " + name);
		try {
			AnnotationWriter out = new AnnotationWriter(new PrintWriter(
					new FileWriter(name)));
			for (MethodQType m : a.getOriginalMethodQTypes()) {
				out.write(m.methodQSig());
			}
			for (FieldQSig f : a.getFieldQSigs()) {
				out.write(f);
			}
			out.flush();
		} catch (IOException e) {
			System.err.println("Exception writing qualifier results from "
					+ name + "\n" + e);
		}
	}

	public static void outputExperimentResults(String name, double kloc,
			Analysis a) {
		Result r = new Result(name, kloc, a);
		r.tableLine();

		JqualPlugin.printLog("missing_" + name, a.dumpMissingStuff());
		JqualPlugin.printlnLog("warningLog", a.toString());
	}

	public void startTable(String title) {
		JqualPlugin.out.println("RESULTS_TABLE_START:" + title);
	}

	public void endTable() {
		JqualPlugin.out.println("RESULTS_TABLE_END");
	}

	@Override
	public Object start(IApplicationContext arg0) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub

	}
}
